package com.pig.util.net;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeMap;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.HTTP;

public class PigRequestAPI {

	public String REQUEST_ENCODE = HTTP.UTF_8;
	public int REQUEST_SO_TIMEOUT = 5000;

	public enum RequestMethodType{
		RequestMethodTypeGet,
		RequestMethodTypePost
	}
	
	public String execute(String url, TreeMap<String, String> params, RequestMethodType requestMethodType){
		
		String result = null;
		
		if(RequestMethodType.RequestMethodTypeGet == requestMethodType){
			result = executeGet(url, params);
		}else if (RequestMethodType.RequestMethodTypePost == requestMethodType){
			result = executePost(url, params);
		}
		
		return result;
	}
	
	private String executePost(String url, TreeMap<String, String> params){
		
		String result = null;
		
		HttpClient client = new DefaultHttpClient();
		client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, REQUEST_SO_TIMEOUT);
		
		HttpPost postMethod = new HttpPost(url);
		ArrayList<BasicNameValuePair> nameValuePairs = serizlizeNameValuePairs(params);
		
		try {
			postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs, REQUEST_ENCODE));
			HttpResponse httpResponse = client.execute(postMethod);
			int statusCode = httpResponse.getStatusLine().getStatusCode();
			
			result = retrieveInputStream(httpResponse.getEntity());
			System.out.println("executePost result: " + result);
			
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return result;
	}
	
	private String executeGet(String url, TreeMap<String, String> params){
		
		String result = null;
		
		String postUrl = serizlizeURL(url, params);
		
		DefaultHttpClient client = new DefaultHttpClient(new BasicHttpParams());
		client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, REQUEST_SO_TIMEOUT);
		
		HttpGet getMethod = new HttpGet(postUrl);
		try {
			HttpResponse httpResponse = client.execute(getMethod);
			int statusCode = httpResponse.getStatusLine().getStatusCode();
			
			result = retrieveInputStream(httpResponse.getEntity());
			System.out.println("executeGet result: " + result);
			
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return result;
	}
	
	public String retrieveInputStream(HttpEntity httpEntity) {
//		Long l = httpEntity.getContentLength();
		int length = (int) httpEntity.getContentLength();
		//the number of bytes of the content, or a negative number if unknown. If the content length is known but exceeds Long.MAX_VALUE, a negative number is returned.
		//System.out.println("length = "+length);
		if (length <= 0) length = 10000;
		StringBuffer stringBuffer = new StringBuffer(length);
		try {
			InputStreamReader inputStreamReader = new InputStreamReader(httpEntity.getContent(), REQUEST_ENCODE);
			char buffer[] = new char[length+1];
			int count;
			while ((count = inputStreamReader.read(buffer, 0, length)) > 0) {
				stringBuffer.append(buffer, 0, count);
			}
		}catch(IOException e){
			e.printStackTrace();
		}
		return stringBuffer.toString();
	}
	
	//
	
	//post
	public static ArrayList<BasicNameValuePair> serizlizeNameValuePairs(TreeMap<String, String> map){
		
		ArrayList<BasicNameValuePair> nameValuePairs = new ArrayList<BasicNameValuePair>(2);
		
		if(null == map || map.size() < 1){
			return nameValuePairs;
		}
		
		Iterator<String> it = map.keySet().iterator();
		while(it.hasNext()){
			String paramKey = it.next();
			String paramValue = map.get(paramKey);
			nameValuePairs.add(new BasicNameValuePair(paramKey, paramValue));
		}
		
		return nameValuePairs;
	}
	
	//get
	public static String serizlizeURL(String baseURL, TreeMap<String, String> params){
		
		String postUrl = "";
		
		int index = baseURL.indexOf("?");
		if(index > 0){
			postUrl = baseURL + "&" + stringFromMap(params);
		}else{
			postUrl = baseURL + "?" + stringFromMap(params);
		}
		
		System.out.println("post url: " + postUrl);
		return postUrl;
	}
	
	public static String stringFromMap(TreeMap<String, String> map){
		
		if(null == map || map.size() < 1){
			return "";
		}
		
		StringBuffer queryUrl = new StringBuffer();
		Iterator<String> it = map.keySet().iterator();
		while(it.hasNext()){
			String paramKey = it.next();
			String paramValue = map.get(paramKey);
			queryUrl.append(paramKey).append("=").append(paramValue).append("&");
		}
		
		String finalUrl = "";
		if(queryUrl.length() > 0){
			finalUrl = queryUrl.substring(0, queryUrl.length() - 1);
		}
		
		return finalUrl;
	}
	
}
